/* uprobe_example.c */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include </usr/share/systemtap/runtime/uprobes/uprobes.h>
/*
 * Usage: insmod uprobe_example.ko pid=<pid> vaddr=<address> [verbose=0]
 * where <pid> identifies the probed process and <address> is the virtual
 * address of the probed instruction.
 */
static int pid = 0;
module_param(pid, int, 0);
MODULE_PARM_DESC(pid, "pid");
static int verbose = 1;
module_param(verbose, int, 0);
MODULE_PARM_DESC(verbose, "verbose");
static long vaddr = 0;
module_param(vaddr, long, 0);
MODULE_PARM_DESC(vaddr, "vaddr");
static int nhits;
static struct uprobe usp;
static void uprobe_handler(struct uprobe *u, struct pt_regs *regs)
{
        nhits++;
        if (verbose)
                printk(KERN_INFO "Hit #%d on probepoint at %#lx\n",
                                nhits, u->vaddr);
}
int __init init_module(void)
{
        int ret;
        usp.pid = pid;
        usp.vaddr = vaddr;
        usp.handler = uprobe_handler;
        printk(KERN_INFO "Registering uprobe on pid %d, vaddr %#lx\n",
                        usp.pid, usp.vaddr);
        ret = register_uprobe(&usp);
        if (ret != 0) {
                printk(KERN_ERR "register_uprobe() failed, returned %d\n", ret);
                return -1;
        }
        return 0;
}
void __exit cleanup_module(void)
{
        printk(KERN_INFO "Unregistering uprobe on pid %d, vaddr %#lx\n",
                        usp.pid, usp.vaddr);
        printk(KERN_INFO "Probepoint was hit %d times\n", nhits);
        unregister_uprobe(&usp);
}
MODULE_LICENSE("GPL");

